package com.ruoyi.recycle.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.lock.LockUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.recycle.constant.OrderInfoConstant;
import com.ruoyi.recycle.domain.*;
import com.ruoyi.recycle.dto.*;
import com.ruoyi.recycle.mapper.*;
import com.ruoyi.recycle.properties.Wxproperties;
import com.ruoyi.recycle.service.IIntegralOrderService;
import com.ruoyi.recycle.service.RecycleRequestLogService;
import com.ruoyi.recycle.utils.OrderNoGenerateUtil;
import com.ruoyi.system.api.util.AesUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.json.JSONArray;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.StampedLock;

/**
 * 积分订单Service业务层处理
 *
 * @author ruoyi
 * @date 2022-05-22
 */
@Service
@Transactional
@Slf4j
@RequiredArgsConstructor
public class IntegralOrderServiceImpl extends ServiceImpl<IntegralOrderMapper, IntegralOrder> implements IIntegralOrderService {

    @Autowired
    private IntegralOrderMapper integralOrderMapper;
    @Resource(name = "redisTemplate")
    private RedisTemplate<String, List<Pocket>> pocketCache;
    @Resource
    private IntegralCommodityMapper integralCommodityMapper;
    @Resource
    private IntegralCommoditySizeMapper integralCommoditySizeMapper;
    @Resource
    private ClientAddressMapper clientAddressMapper;
    @Resource
    private ClientUserManagementMapper clientUserManagementMapper;
    @Resource
    private IntegralOrderCommodityMapper integralOrderCommodityMapper;
    @Resource
    private MerchatBillRecordMapper merchatBillRecordMapper;
    @Resource
    private OrderNoGenerateUtil orderNoGenerateUtil;
    @Resource
    private WechatPaymentService wechatPaymentService;
    @Resource
    private RecycleRequestLogService recycleRequestLogService;

    private final Wxproperties wxproperties;

    private final StampedLock lock = LockUtil.createStampLock();

    private final static String POCKET_PREFIX = "POCKET";

    /**
     * 查询积分订单
     *
     * @param id 积分订单主键
     * @return 积分订单
     */
    @Override
    public IntegralOrder selectIntegralOrderById(Long id) {
        return integralOrderMapper.selectIntegralOrderById(id);
    }

    /**
     * 查询积分订单列表
     *
     * @param integralOrder 积分订单
     * @return 积分订单
     */
    @Override
    public List<IntegralOrder> selectIntegralOrderList(IntegralOrder integralOrder) {
        return integralOrderMapper.selectIntegralOrderList(integralOrder);
    }

    /**
     * 新增积分订单
     *
     * @param integralOrder 积分订单
     * @return 结果
     */
    @Override
    public int insertIntegralOrder(IntegralOrder integralOrder) {
        return integralOrderMapper.insertIntegralOrder(integralOrder);
    }

    /**
     * 修改积分订单
     *
     * @param integralOrder 积分订单
     * @return 结果
     */
    @Override
    public int updateIntegralOrder(IntegralOrder integralOrder) {
        return integralOrderMapper.updateIntegralOrder(integralOrder);
    }

    /**
     * 批量删除积分订单
     *
     * @param ids 需要删除的积分订单主键
     * @return 结果
     */
    @Override
    public int deleteIntegralOrderByIds(Long[] ids) {
        return integralOrderMapper.deleteIntegralOrderByIds(ids);
    }

    /**
     * 删除积分订单信息
     *
     * @param id 积分订单主键
     * @return 结果
     */
    @Override
    public int deleteIntegralOrderById(Long id) {
        return integralOrderMapper.deleteIntegralOrderById(id);
    }

    @Override
    public AjaxResult statisticsMoney(IntegralOrderDTO queryDTO) {

        IntegralOrder integralOrder = new IntegralOrder();
        BeanUtils.copyProperties(queryDTO, integralOrder);
        final LambdaQueryWrapper<IntegralOrder> wrapper = Wrappers.lambdaQuery(integralOrder);
        if (queryDTO.getSearchTimeBegin() != null) {
            wrapper.ge(IntegralOrder::getCreatedTime, queryDTO.getSearchTimeBegin());
        } else if (queryDTO.getSearchTimeEnd() != null) {
            wrapper.le(IntegralOrder::getCreatedTime, queryDTO.getSearchTimeEnd());
        }
        wrapper.orderByDesc(IntegralOrder::getCreatedTime);

        List<IntegralOrder> integralOrders = integralOrderMapper.selectList(wrapper);
        BigDecimal totalMoney = integralOrders.stream().map(aa -> aa.getMoney()).reduce(BigDecimal.ZERO, BigDecimal::add);
        Long totalIntegral = 0l;
        for (IntegralOrder i : integralOrders) {
            totalIntegral+=i.getIntegral();
        }


        Page<IntegralOrder> integralOrderPage = this.page(new Page<IntegralOrder>().setCurrent(queryDTO.getCurrentPage()).setSize(queryDTO.getPageSize()), wrapper);

        return AjaxResult.success().put("integralOrders", integralOrderPage).put("wxMoney", totalMoney).put("totalIntegral",totalIntegral);
    }


    @Override
    public AjaxResult deletePocketItem(PocketReq pocketReq) {
        final String key = POCKET_PREFIX + pocketReq.getUserId();
        List<Pocket> pocketList = pocketCache.opsForValue().get(key);

        if (CollUtil.isEmpty(pocketList)) {
            return AjaxResult.error("购物车为空");
        }


        List<Pocket> deletePocketItems = new ArrayList<>();

        JSONArray jsonArray = new JSONArray(pocketList);

        pocketList = new ArrayList<>();

        for (int i = 0; i < jsonArray.length(); i++) {
            Pocket pocket = new Pocket();
            org.json.JSONObject object = jsonArray.getJSONObject(i);
            String integralCommodityStr = object.get("integralCommodity").toString();
            IntegralCommodity integralCommodity = JSON.parseObject(integralCommodityStr, IntegralCommodity.class);

            String integralCommoditySizeStr = object.get("integralCommoditySize").toString();
            IntegralCommoditySize integralCommoditySize = JSON.parseObject(integralCommoditySizeStr, IntegralCommoditySize.class);

            pocket.setCreateDate(object.get("createDate").toString());
            pocket.setQuantity((int)object.get("quantity"));
            Integer userId = (int)object.get("userId");
            pocket.setUserId(userId.longValue());
            pocket.setIntegralCommodity(integralCommodity);
            pocket.setIntegralCommoditySize(integralCommoditySize);
            pocketList.add(pocket);
        }

        for (Pocket pocket : pocketList) {
            if (ObjectUtils.isNotEmpty(pocket.getIntegralCommodity()) &&
                    ObjectUtils.isNotEmpty(pocket.getIntegralCommoditySize()) &&
                    pocket.getIntegralCommodity().getId() == pocketReq.getCommodityId() &&
                    pocket.getIntegralCommoditySize().getId() == pocketReq.getSizeId()){
                deletePocketItems.add(pocket);
            }
        }

        if (deletePocketItems.size() > 0) {
            Pocket product = deletePocketItems.get(0);
            if (product.getQuantity() > pocketReq.getQuantity()) {
                pocketList.remove(product);
                product.setQuantity(product.getQuantity() - pocketReq.getQuantity());
                pocketList.add(product);
            } else if (product.getQuantity() == pocketReq.getQuantity()){
                pocketList.removeAll(deletePocketItems);
            }else {
                return AjaxResult.error("删除的数量不允许大于购物车中的数量");
            }
        }
        pocketCache.opsForValue().set(key, pocketList, 30 * 3, TimeUnit.DAYS);
        return AjaxResult.success("删除成功");
    }


    @Override
    public AjaxResult pocketCreateOrder(PocketCreateOrderReq pocketCreateOrderReq) {

        ClientAddress clientAddress = clientAddressMapper.selectById(pocketCreateOrderReq.getAddressId());
        ClientUserManagement clientUserManagement = clientUserManagementMapper.selectById(pocketCreateOrderReq.getUserId());
        if (ObjectUtils.isEmpty(clientAddress)){
            return AjaxResult.error("地址信息异常，请检查配置地址信息");
        }

        final String address = clientAddress.getClientName() + " " + clientAddress.getPhone() + " " + clientAddress.getCity()  +" " + clientAddress.getAddress();

        //一个商品一个订单，数量 可以为复数
        List<Long> orderIds = new ArrayList<>();
        //总积分
        Long totalIntegral = 0l;
        //总金额
        BigDecimal totalMoney = new BigDecimal(0);

        for (PocketReq pocketReq : pocketCreateOrderReq.getPocketReqList()) {
            IntegralCommodity commodity = integralCommodityMapper.selectById(pocketReq.getCommodityId());
            if (ObjectUtils.isEmpty(commodity)){
                return AjaxResult.error("商品已下架，请挑选其他商品");
            }
            IntegralCommoditySize integralCommoditySize = integralCommoditySizeMapper.selectById(pocketReq.getSizeId());

            if (ObjectUtils.isEmpty(integralCommoditySize)){
                return AjaxResult.error("对应规格已下架，请挑选其他规格");
            }

            if (integralCommoditySize.getInventory() < pocketReq.getQuantity()){
                return AjaxResult.error("商品库存不足，请挑选其他规格");
            }

            //减扣库存
            final long writeLock = lock.writeLock();
            try {
                integralCommoditySize.setInventory(integralCommoditySize.getInventory() - pocketReq.getQuantity());
                integralCommoditySizeMapper.updateById(integralCommoditySize);
            } catch (Exception e) {
                log.error("更新商品库存异常{}",e);
                return AjaxResult.error("商品库存不足，请挑选其他规格");
            } finally {
                lock.unlock(writeLock);
            }

            IntegralOrder integralOrder = new IntegralOrder();
            integralOrder.setPhone(clientAddress.getPhone());
            integralOrder.setCreatedBy(clientUserManagement.getUserName());
            integralOrder.setCreatedTime(new Date());
            integralOrder.setIntegral(pocketReq.getIntegral());
            integralOrder.setQuantity(pocketReq.getQuantity());
            integralOrder.setCommodityId(commodity.getId());
            integralOrder.setCommodity(commodity.getCommodityName());
            BigDecimal money = pocketReq.getMoney().multiply(new BigDecimal(pocketReq.getQuantity()));
            integralOrder.setMoney(money);
            integralOrder.setShippingAddress(address);
            integralOrder.setClientId(pocketCreateOrderReq.getUserId().intValue());
            Boolean flag = true;
            if (pocketReq.getMoney().compareTo(BigDecimal.ZERO) == 0) {
                integralOrder.setStatus("待发货");
                integralOrder.setPayType("蓝星币");
                integralOrder.setPayTime(new Date());
                //减扣用户积分
                if (pocketReq.getIntegral() != null && pocketReq.getIntegral()>0) {
                    clientUserManagement.setIntegral(clientUserManagement.getIntegral() - pocketReq.getIntegral());
                    clientUserManagementMapper.updateById(clientUserManagement);
                }
                flag = false;
            }else {
                integralOrder.setStatus("待付款");
            }
            integralOrder.setCommodityImg(commodity.getPoster());
            integralOrder.setPostage(commodity.getPostage());

            integralOrderMapper.insert(integralOrder);
            if (pocketReq.getMoney().compareTo(BigDecimal.ZERO) == 0) {
                if (pocketReq.getIntegral() != null && pocketReq.getIntegral()>0) {
                    //记录下单积分
                    BillRecord billRecord = new BillRecord();
                    billRecord.setOrderNo(integralOrder.getId().toString());
                    billRecord.setCreateTime(new Date());
                    billRecord.setOutput(BigDecimal.valueOf(integralOrder.getIntegral()));
                    billRecord.setUserId(clientUserManagement.getId());
                    billRecord.setUserType(1);
                    billRecord.setType(4);
                    merchatBillRecordMapper.insert(billRecord);
                }
            }

            //更新订单商品尺寸中间表
            IntegralOrderCommodity integralOrderCommodity = new IntegralOrderCommodity();
            integralOrderCommodity.setCommodityId(commodity.getId());
            integralOrderCommodity.setOrderId(integralOrder.getId());
            integralOrderCommodity.setQuantity(pocketReq.getQuantity());
            integralOrderCommodity.setSizeId(pocketReq.getSizeId());
            integralOrderCommodity.setCreatedTime(new Date());
            integralOrderCommodity.setCreatedBy("admin");
            integralOrderCommodityMapper.insert(integralOrderCommodity);
            if (flag) {
                orderIds.add(integralOrder.getId());
                totalIntegral += pocketReq.getIntegral();
                totalMoney = totalMoney.add(pocketReq.getMoney());
            }
        }

        //下单成功需要清理掉购物车的数据
        try{
            for (PocketReq pocketReq : pocketCreateOrderReq.getPocketReqList()) {
                deletePocketItem(pocketReq);
            }

        }catch (Exception e){
            log.error("清理购物车异常",e.getMessage(),e);
        }

        return AjaxResult.success(orderIds).put("totalMoney",totalMoney).put("totalIntegral",totalIntegral);
    }

    @Override
    public AjaxResult payment(Payment payment) {

        ClientUserManagement clientUserManagement = clientUserManagementMapper.selectById(payment.getUserId());

        //校验支付密码
//        if (StringUtils.isEmpty(payment.getPassword()) || !payment.getPassword().equals(clientUserManagement.getPassword())){
//            Map<String, String> map = new HashMap<>();
//            map.put("code","500");
//            map.put("result","您输入的支付密码错误");
//            return map;
//        }
        if (payment.getTotalIntegral() > clientUserManagement.getIntegral()){
            Map<String, String> map = new HashMap<>();
            map.put("code","500");
            map.put("result","您当前积分不足以支付当前订单,该订单总需要积分为："+ payment.getTotalIntegral() + "您当前的积分为：" + clientUserManagement.getIntegral());
            return AjaxResult.error("您当前积分不足以支付当前订单,该订单总需要积分为："+ payment.getTotalIntegral() + "您当前的积分为：" + clientUserManagement.getIntegral()).put("resultMap",map);
        }

        //调起微信支付
        String orderId = orderNoGenerateUtil.getIncr(OrderInfoConstant.INTEGRAL_ORDER);
        PaymentDTO paymentDTO = new PaymentDTO();
        paymentDTO.setOrderNo(orderId);
        paymentDTO.setTotalFee(payment.getTotalMoney());
        paymentDTO.setOpenId(clientUserManagement.getOpenid());
        paymentDTO.setProductDetail("商品购买");
        paymentDTO.setAccount(clientUserManagement.getUserName());

        paymentDTO.setAppId(wxproperties.getClientAppId());
        paymentDTO.setNotifyUrl("https://bluestarhuman.com/recycle/clientProgram/shopping/payCallBack");
        Map<String, String> pay = wechatPaymentService.pay(paymentDTO);
        pay.put("orderNo",orderId);
        return AjaxResult.success(pay);
    }

    @Override
    public AjaxResult paymentEnd(Payment payment) {
        ClientUserManagement clientUserManagement = clientUserManagementMapper.selectById(payment.getUserId());

        String payType = "现金";
        if (payment.getTotalIntegral() != null && payment.getTotalIntegral() > 0){
            payType = payType + "+蓝星币";
        }

        //减扣用户积分
        clientUserManagement.setIntegral(clientUserManagement.getIntegral() - payment.getTotalIntegral());
        clientUserManagementMapper.updateById(clientUserManagement);

        //记录用户积分记录
        for (Long id : payment.getIds()) {

            IntegralOrder integralOrder = integralOrderMapper.selectById(id);

            BillRecord billRecord = new BillRecord();
            billRecord.setOrderNo(id.toString());
            billRecord.setCreateTime(new Date());
            billRecord.setOutput(BigDecimal.valueOf(integralOrder.getIntegral()));
            billRecord.setUserId(clientUserManagement.getId());
            billRecord.setUserType(1);
            billRecord.setType(4);
            merchatBillRecordMapper.insert(billRecord);

            //修改订单状态
            integralOrder.setPaymentNo(payment.getOrderNo());
            integralOrder.setPayTime(new Date());
            integralOrder.setPayType(payType);
            integralOrder.setUpdatedTime(new Date());
            integralOrder.setUpdatedBy("WX");
            integralOrderMapper.updateById(integralOrder);
        }

        return AjaxResult.success("结算成功");
    }


    @Override
    public AjaxResult applicationForDrawback(Long id, String remark) {
        IntegralOrder integralOrder = integralOrderMapper.selectById(id);
        integralOrder.setRemark(remark);
        integralOrder.setStatus("退款中");
        integralOrderMapper.updateById(integralOrder);
        return AjaxResult.success("发起退款成功");
    }


    @Override
    public AjaxResult applicationForDrawback(Long id) {
        String refund = "";
        IntegralOrder integralOrder = integralOrderMapper.selectById(id);
        //判断是纯积分还是纯现金或者是积分+现金
        if (ObjectUtils.isNotEmpty(integralOrder.getIntegral()) && integralOrder.getIntegral() > 0
            && (ObjectUtils.isEmpty(integralOrder.getMoney()) ||  integralOrder.getMoney().compareTo(BigDecimal.ZERO) == 0)){
           //纯积分
            //退积分
            ClientUserManagement clientUserManagement = clientUserManagementMapper.selectById(integralOrder.getClientId());

            //记录退积分记录
            BillRecord billRecord = new BillRecord();
            billRecord.setOrderNo(id.toString());
            billRecord.setCreateTime(new Date());
            billRecord.setIncome(BigDecimal.valueOf(integralOrder.getIntegral()));
            billRecord.setUserId(clientUserManagement.getId());
            billRecord.setUserType(1);
            billRecord.setType(7);
            merchatBillRecordMapper.insert(billRecord);

            //更新退的积分到用户账户
            clientUserManagement.setIntegral(clientUserManagement.getIntegral() + integralOrder.getIntegral());
            clientUserManagement.setUpdatedTime(new Date());
            clientUserManagementMapper.updateById(clientUserManagement);

            integralOrder.setStatus("退款成功");
            integralOrder.setUpdatedTime(new Date());
            integralOrderMapper.updateById(integralOrder);
            refund = "退款成功";
        }else if ((ObjectUtils.isEmpty(integralOrder.getIntegral()) || integralOrder.getIntegral() == 0)
                && (ObjectUtils.isEmpty(integralOrder.getMoney()) ||  integralOrder.getMoney().compareTo(BigDecimal.ZERO) == 0)){
           //纯现金
            //调起微信退款
            refund = wechatPaymentService.refund(integralOrder.getPaymentNo(), integralOrder.getMoney());
            if ("退款成功".equals(refund)){
                integralOrder.setStatus("退款成功");
                integralOrder.setUpdatedTime(new Date());
                integralOrderMapper.updateById(integralOrder);
            }

        }else {
            //积分+现金
            //退积分
            ClientUserManagement clientUserManagement = clientUserManagementMapper.selectById(integralOrder.getClientId());

            //记录退积分记录
            BillRecord billRecord = new BillRecord();
            billRecord.setOrderNo(id.toString());
            billRecord.setCreateTime(new Date());
            billRecord.setIncome(BigDecimal.valueOf(integralOrder.getIntegral()));
            billRecord.setUserId(clientUserManagement.getId());
            billRecord.setUserType(1);
            billRecord.setType(7);
            merchatBillRecordMapper.insert(billRecord);

            //更新退的积分到用户账户
            clientUserManagement.setIntegral(clientUserManagement.getIntegral() + integralOrder.getIntegral());
            clientUserManagement.setUpdatedTime(new Date());
            clientUserManagementMapper.updateById(clientUserManagement);
            //调起微信退款
            refund = wechatPaymentService.refund(integralOrder.getPaymentNo(), integralOrder.getMoney());
            if ("退款成功".equals(refund)){
                integralOrder.setStatus("退款成功");
                integralOrder.setUpdatedTime(new Date());
                integralOrderMapper.updateById(integralOrder);
            }
        }

        return AjaxResult.success(refund);
    }

    @Override
    @SneakyThrows
    public Map<String, String> payCallBack(HttpServletRequest request) {
        log.debug("微信支付回调数据：" + String.valueOf(request));
        Map<String, String> returnMap = new HashMap<>();
        try {
            final String requestBody = wechatPaymentService.getRequestBody(request);
            log.info("回调接收到的参数为：{}", JSON.toJSONString(requestBody));

            if (wechatPaymentService.verifiedSign(request, requestBody)) {
                //微信支付通知实体类
                log.info("进行微信支付回调信息JSON格式转换,转换的JSON是：{}",requestBody);
                PayCallBackInfo payCallBackInfo = JSONObject.parseObject(requestBody, PayCallBackInfo.class);
                log.info("微信支付通知实体类解析成功，解析数据为：{}",payCallBackInfo.toString());
                //如果支付成功
                if ("TRANSACTION.SUCCESS".equals(payCallBackInfo.getEvent_type())) {
                    //通知资源数据
                    PayCallBackInfo.Resource resource = payCallBackInfo.getResource();
                    //解密后资源数据
                    String notifyResourceStr = AesUtil.decryptToString(wxproperties.getApiV3Key().getBytes(StandardCharsets.UTF_8),
                            resource.getAssociated_data().getBytes(StandardCharsets.UTF_8),
                            resource.getNonce().getBytes(StandardCharsets.UTF_8), resource.getCiphertext());
                    log.info("微信支付解密后资源数据成功，解析数据为：{}",notifyResourceStr);
                    //通知资源数据对象
                    ResourceInfo decryptResource = JSONObject.parseObject(notifyResourceStr, ResourceInfo.class);
                    final String outTradeNo = decryptResource.getOut_trade_no();
                    final Integer total = decryptResource.getAmount().getTotal();
                    BigDecimal amount = integralOrderMapper.getCountMoney(outTradeNo);

                    BigDecimal amountPay = (new BigDecimal(total).divide(new BigDecimal("100"))).setScale(2);
                    if (amountPay.compareTo(amount)!=0){
                        returnMap.put("code", "500");
                        returnMap.put("message", "微信支付金额与蓝星人订单记录金额不一致");
                        //记录日志
                        recycleRequestLogService.save(new RecycleRequestLog().
                                setRequestData(decryptResource.toString()).
                                setResponseData(returnMap.toString()).
                                setRemark("警告：微信支付回调信息异常信息请注意处理").
                                setLogType("微信支付").
                                setCreateBy("ADMIN").
                                setCreateDate(new Date()).
                                setRequestUser("微信").
                                setResponseUser("蓝星人"));
                        return returnMap;
                    }
                    List<IntegralOrder> integralOrders = integralOrderMapper.selectList(new LambdaQueryWrapper<>(new IntegralOrder()).eq(IntegralOrder::getPaymentNo, outTradeNo));
                    for (IntegralOrder integralOrder : integralOrders) {
                        integralOrder.setStatus("待发货");
                        integralOrder.setUpdatedTime(new Date());
                        integralOrderMapper.updateById(integralOrder);
                    }
                    returnMap.put("code", "SUCCESS");
                }
            }
        } catch (Exception e) {
            //记录日志
            recycleRequestLogService.save(new RecycleRequestLog().
                    setRequestData(request.toString()).
                    setResponseData(e.getMessage()).
                    setRemark("警告：微信支付回调信息异常信息请注意处理").
                    setLogType("微信支付").
                    setCreateBy("ADMIN").
                    setCreateDate(new Date()).
                    setRequestUser("微信").
                    setResponseUser("蓝星人"));

            log.error("支付失败原因:{}",e.getMessage(),e);
            returnMap.put("code", "500");
            returnMap.put("message", "系统错误");
            return returnMap;
        }

        recycleRequestLogService.save(new RecycleRequestLog().
                setRequestData(request.toString()).
                setResponseData(returnMap.toString()).
                setRemark("微信支付回调信息").
                setLogType("微信支付").
                setCreateBy("ADMIN").
                setCreateDate(new Date()).
                setRequestUser("微信").
                setResponseUser("蓝星人"));
        return returnMap;
    }

    @Override
    public AjaxResult miniClientGetClientIntegralOrder(IntegralOrderDTO queryDTO) {

        final IntegralOrder integralOrder = new IntegralOrder();
        BeanUtils.copyProperties(queryDTO, integralOrder);
        final LambdaQueryWrapper<IntegralOrder> wrapper = Wrappers.lambdaQuery(integralOrder);
        if (queryDTO.getSearchTimeBegin() != null) {
            wrapper.ge(IntegralOrder::getCreatedTime, queryDTO.getSearchTimeBegin());
        }
        if (queryDTO.getSearchTimeEnd() != null) {
            wrapper.le(IntegralOrder::getCreatedTime, queryDTO.getSearchTimeEnd());
        }
        wrapper.orderByDesc(IntegralOrder::getCreatedTime);

        IPage<IntegralOrder> integralOrderPage = page(new Page<>(queryDTO.getCurrentPage(), queryDTO.getPageSize(), true), wrapper);

        return AjaxResult.success(integralOrderPage);
    }


    @Override
    public AjaxResult cancelIntegralOrder(String orderNo) {
        //取消订单，归还库存
        IntegralOrder integralOrder = integralOrderMapper.selectById(orderNo);
        if (!"待付款".equals(integralOrder.getStatus())){
            return AjaxResult.error("只有待付款状态的订单可以取消，已支付的订单请申请退款，如若不是请忽略");
        }
        List<IntegralOrderCommodity> integralOrderCommodities = integralOrderCommodityMapper.selectList(new LambdaQueryWrapper<IntegralOrderCommodity>().eq(IntegralOrderCommodity::getOrderId, integralOrder.getId()));

        for (IntegralOrderCommodity integralOrderCommodity : integralOrderCommodities) {
            IntegralCommoditySize integralCommoditySize = integralCommoditySizeMapper.selectById(integralOrderCommodity.getSizeId());
            integralCommoditySize.setInventory(integralCommoditySize.getInventory() + integralOrderCommodity.getQuantity());
            integralCommoditySizeMapper.updateById(integralCommoditySize);
        }
        integralOrder.setStatus("已取消");
        integralOrderMapper.updateById(integralOrder);

        return AjaxResult.success("取消成功");
    }


    private void putIntoPocket(Pocket pocket) {
        final String pocketKey = POCKET_PREFIX + pocket.getUserId();
        ValueOperations<String, List<Pocket>> opsForValue = pocketCache.opsForValue();
        List<Pocket> existPocketProducts = opsForValue.get(pocketKey);

        if (CollUtil.isNotEmpty(existPocketProducts)) {

            final boolean match = existPocketProducts.stream().anyMatch(existPocket -> {
                if (existPocket.getIntegralCommodity() != null && existPocket.getIntegralCommoditySize() != null) {
                    Long commodityId = existPocket.getIntegralCommodity().getId();
                    Long sizeId = existPocket.getIntegralCommoditySize().getId();
                    if (pocket.getIntegralCommodity().getId() == commodityId && pocket.getIntegralCommoditySize().getId() == sizeId) {
                        return true;
                    }
                }
                return false;
            });
            if (match) {
                for (Pocket existPocketProduct : existPocketProducts) {
                    if (existPocketProduct.getIntegralCommodity().getId() == pocket.getIntegralCommodity().getId() && existPocketProduct.getIntegralCommoditySize().getId() == pocket.getIntegralCommoditySize().getId()) {
                        existPocketProduct.setQuantity(existPocketProduct.getQuantity() + pocket.getQuantity());
                    }
                }
                opsForValue.set(pocketKey, existPocketProducts, 30 * 3, TimeUnit.DAYS);
            } else {
                opsForValue.set(pocketKey, CollUtil.newArrayList(pocket), 30 * 3, TimeUnit.DAYS);
            }
        }else {
            opsForValue.set(pocketKey, CollUtil.newArrayList(pocket), 30 * 3, TimeUnit.DAYS);
        }
    }

}
